package teamCservlets;

import java.text.SimpleDateFormat;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;


public class DefectActionsServlet extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		/* Requests supported by this servlet are:
		 * - store a new defect, extracting data from the new defect form
		 * - update an existing defect, extracting data from the defect details form
		 * - submit a defect for closure, extracting data from the close defect form
		 * - send an email, extracting data from the email form
		 */

		// Make sure a user is logged in, and if not, redirect to the login page
		PersonBean	authUser = null;
		HttpSession session = request.getSession();
		authUser = (PersonBean) session.getAttribute("user");
		if ((authUser == null) || (authUser.getId() == -1)) {
			response.sendRedirect("login.jsp");
		}

		// Determine which action is requested, and service the request.
		// The default action, if none other is specified, is to return
		// to the homepage.
		if (request.getParameter("btnStoreNewDefect") != null) {
			storeNewDefect(request, response, authUser.getId());
		} else if (request.getParameter("btnStoreUpdatedDefect") != null) {
			storeUpdatedDefect(request, response);
		} else if (request.getParameter("btnStoreClosedDefect") != null) {
			storeClosedDefect(request, response);
		} else if (request.getParameter("btnSendEmail") != null) {
			sendEmail(request, response);
		} else if (request.getParameter("btnGoToHomepage") != null) {
			displayHomePage(request, response);
		} else {
			displayHomePage(request, response);
		}
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		doPost(request, response);
	}

	private void storeNewDefect(
			HttpServletRequest request,
			HttpServletResponse response,
			int submitterId)
			throws ServletException, IOException {

		// The user has clicked Save on the Create Defect form, so the form data needs to
		// be processed.  The steps are:
		// 1. Get the data values from the form and put them into the newDefect object,
		// which is a session attribute.  Set any non-user-entered fields needed for
		// storing the defect in the database.
		// 2. Validate that newDefect has all of the required fields populated.  If any are
		// missing, build an error message and forward the request to createdefect.jsp, to
		// redisplay the form with the error message, retaining any user-entered data by
		// getting it from the newDefect object.
		// 3. If all required fields are populated, write the new defect to the database and
		// remove the newDefect attribute from the session, since it's no longer needed
		// 4. Based on status of the database call, display status.jsp, indicating whether
		// or not the action was successful.

		String nextPage = null;

		// Get a reference to the newDefect object in the session.
		HttpSession session = request.getSession();
		DefectBean newDefect = (DefectBean)session.getAttribute("newDefect");

		if(newDefect == null) {
			request.setAttribute("msgType", "error");
			request.setAttribute("message", "Error storing new defect in the database.");
			nextPage = "status.jsp";
			RequestDispatcher dispatcher = request.getRequestDispatcher(nextPage);
			dispatcher.forward(request, response);
		}

		// Get the user-selected application, priority, summary, and description from
		// the form.  Put each value into newDefect.
		newDefect.setApplicationID(Integer.parseInt(request.getParameter("selApplicationId")));
		newDefect.setPriority(request.getParameter("selPriority"));
		newDefect.setSummary(request.getParameter("txtSummary"));
		newDefect.setDetailedDescription(request.getParameter("txtDescription"));

		// If the user assigned the defect, set status to ASSIGNED, otherwise, set status to NEW.
		// In either case, set the assignee ID.  A value of -1 indicates the defect is not
		// assigned to anyone.
		int assigneeId = Integer.parseInt(request.getParameter("selAssigneeId"));
		newDefect.setAssigneeID(assigneeId);
		if (assigneeId == -1) {
			newDefect.setStatus("NEW");
		} else {
			newDefect.setStatus("ASSIGNED");
		}

		// Set the opened date to today.
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        newDefect.setStringOpenDate(sdf.format(new Date()));

        // Set the submitter ID to the current user.
        newDefect.setSubmitterID(submitterId);

		// If the new defect is valid, meaning all necessary data has been filled in,
		// write it to the database.
		if (newDefect.isValidNewDefect()) {
			DatabaseInterfaceDefect db = new DatabaseInterfaceDefect();
			boolean status = false;
			status = db.writeNewDefect(
					newDefect.getApplicationID(),
					newDefect.getSubmitterID(),
					newDefect.getAssigneeID(),
					newDefect.getPriority(),
					newDefect.getSummary(),
					newDefect.getDetailedDescription(),
					newDefect.getStringOpenDate());

			// A status page will be displayed.  Set it up to display either success or
			// error status.
			nextPage = "status.jsp";
			if (status) {
				request.setAttribute("msgType", "success");
				request.setAttribute("message", "New defect has been stored in the database.");
			} else {
				request.setAttribute("msgType", "error");
				request.setAttribute("message", "Error storing new defect in the database.");
			}
			// The newDefect attribute no longer needed.  Delete it from the session.
			session.removeAttribute("newDefect");

			/*// Display status of the database call, plus the data values
			response.setContentType("text/html");
			PrintWriter out = response.getWriter();
			out.println("<html>");
			out.println("<head>");
			out.println("<title>Team C Defect System</title>");
			out.println("</head>");
			out.println("<body>");
			out.println("<p>Result of call to db.writeNewDefect: " + status + "</p>");
			out.println("<p>Contents of newDefect after filling it: " + newDefect.toString() + "</p>");
			out.println("<p>App ID: " + newDefect.getApplicationID() + "</p>");
			out.println("<p>Assignee ID: " + newDefect.getAssigneeID() + "</p>");
			out.println("<p>Submitter ID: " + newDefect.getSubmitterID() + "</p>");
			out.println("<p>Status: " + newDefect.getStatus() + "</p>");
			out.println("<p>Open date: " + newDefect.getStringOpenDate() + "</p>");
			out.println("<p>Priority: " + newDefect.getPriority() + "</p>");
			out.println("<p>Summary: " + newDefect.getSummary() + "</p>");
			out.println("<p>Description: " + newDefect.getDetailedDescription() + "</p>");
			out.println("<p>Is valid new defect: " + newDefect.isValidNewDefect() + "</p>");
			out.println("</body>");
			out.println("</html>"); */

		} else {
			// The newDefect isn't valid.  This would only be because the user didn't
			// fill in a required field.  Build an error message to be displayed on
			// createdefect.jsp along with the current values in newDefect, which the
			// user previously entered.
			request.setAttribute("message", "Please fill in all required fields");
			nextPage = "createdefect.jsp";
		}

		// Forward the request to the appropriate page, as determined above.
		RequestDispatcher dispatcher = request.getRequestDispatcher(nextPage);
		dispatcher.forward(request, response);

}

	private void storeUpdatedDefect(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// The user has clicked the "Save" (a.k.a. btnStoreUpdatedDefect) button
		// on the updatedefect.jsp page.  We must now do the following:
		//
		// 1. Get the session itself.
		//
		// 2. Get the actual defect object from the session.
		//
		// 3. Get four more objects from the session listed below:
		//		a. "chosenPriority" which is the new priority selected from the drop down box.
		//		b. "chosenAssignee" which is the new assigneeID selected from the drop down box.
		//		c. "textSummary" which is the text from the summary box.
		//		d. "textDescription" which is the text from the detailed description box.
		//
		// 4. Assign the four DefectBean fields using items (3-a) through (3-d) above.
		//
		// 5. Write this defect back to the database.
		//
		// 6. Return to the

		// Start by setting up logging.


		String nextPage = null;


		// Part 1: Get the session itself.

		HttpSession session = request.getSession();

		// Part 2: Get the defect from the session.
		DefectBean updatedDefect = (DefectBean) session.getAttribute("currentDefect");

		if(updatedDefect == null) {
			request.setAttribute("msgType", "error");
			request.setAttribute("message", "Error getting updated defect from session.");
			nextPage = "status.jsp";
			RequestDispatcher dispatcher = request.getRequestDispatcher(nextPage);
			dispatcher.forward(request, response);
		}

		// Part 3: Get the session attributes needed for the update.

		int newAssigneeID = Integer.parseInt(request.getParameter("chosenAssignee"));
		String newPriority = new String(request.getParameter("chosenPriority"));
		String newSummary = new String(request.getParameter("textSummary"));
		String newDescription = new String(request.getParameter("textDescription"));

		// Part 4: Then update the defect itself.

		updatedDefect.setAssigneeID(newAssigneeID);
		updatedDefect.setPriority(newPriority);
		updatedDefect.setSummary(newSummary);
		updatedDefect.setDetailedDescription(newDescription);

		// Build a page displaying an "under construction" message.
		/*response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<head>");
		out.println("<title>Team C Defect System</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<p>" + "Defect retrieved with defect ID: " + updatedDefect.getDefectID() + "</p>");
		out.println("<p>" + "Assignee ID: " + updatedDefect.getAssigneeID() + "</p>");
		out.println("<p>" + "Priority: " + updatedDefect.getPriority() + "</p>");
		out.println("<p>" + "Summary: " + updatedDefect.getSummary() + "</p>");
		out.println("<p>" + "Description: " + updatedDefect.getDetailedDescription() + "</p>");
		out.println("</body>");
		out.println("</html>");*/


		DatabaseInterfaceDefect interfaceDB = new DatabaseInterfaceDefect();

		// Set up the status based on whether we have an assignee or not.
		String status;
		if(updatedDefect.getAssigneeID() == -1) {
			status = new String("NEW");
		} else {
			status = new String("ASSIGNED");
		}

		// Write to the database.
		boolean dbResult = interfaceDB.writeModifiedDefect(updatedDefect.getDefectID(),
			updatedDefect.getAssigneeID(), status, updatedDefect.getPriority(),
			updatedDefect.getSummary(), updatedDefect.getDetailedDescription(),
			null, null);

		// Part 6: Go to status page.
		if(dbResult)
		{
			request.setAttribute("msgType", "success");
			request.setAttribute("message", "The issue has been updated.");
		}
		else
		{
			request.setAttribute("msgType", "error");
			request.setAttribute("message", "Error storing updated defect in the database.");
		}

		nextPage = new String("status.jsp");
		// Forward the request to the appropriate page or servlet, as determined above.
		RequestDispatcher dispatcher = request.getRequestDispatcher(nextPage);
		dispatcher.forward(request, response);
	} // End of method to store an updated Defect.

	private void storeClosedDefect(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {


		HttpSession session = request.getSession();

		// Get the current defect ID from the session; this is the one to be closed.
		int defectId = (Integer)session.getAttribute("currentDefectId");

		DatabaseInterfaceDefect dbDefect = new DatabaseInterfaceDefect();
		String nextPage = null;
		DefectBean	defect = null;
		defect = dbDefect.getOpenDefect(defectId);

		// Checking logic: go to status page if defect is null (i.e. database connection failure!)

		if(defect==null)
		{
			request.setAttribute("msgType", "error");
			request.setAttribute("message", "Error storing defect with closure in the database.");
			nextPage = new String("status.jsp");
			RequestDispatcher dispatcher = request.getRequestDispatcher(nextPage);
			dispatcher.forward(request, response);
		}

		java.text.DateFormat dateFormat = new java.text.SimpleDateFormat("yyyy/MM/dd");
		java.util.Date date = new java.util.Date();

		request.setAttribute("defectid", Integer.toString(defectId));
		request.setAttribute("summary", defect.getSummary());
		request.setAttribute("resolutiondate", dateFormat.format(date));
		request.setAttribute("txtResolutionNote", (String) request.getParameter("txtResolutionNote"));

		// The newDefect attribute no longer needed.  Delete it from the session.
		session.removeAttribute("newDefect");

		if(((String) request.getParameter("txtResolutionNote")).equals(""))
		{
			nextPage = "closedefect.jsp";
			request.setAttribute("resolvemessage", "You need to enter a resolution Note.");
		}
		else
		{
			dbDefect = new DatabaseInterfaceDefect();
			nextPage = "status.jsp";
			if(dbDefect.writeClosedDefect(defectId, (String) request.getParameter("txtResolutionNote"), dateFormat.format(date)))
			{
				request.setAttribute("msgType", "success");
				request.setAttribute("message", "The issue has been closed.");
			}
			else
			{
				request.setAttribute("msgType", "error");
				request.setAttribute("message", "Error storing new defect in the database.");
			}
		}


		// Forward the request to the appropriate page or servlet, as determined above.
		RequestDispatcher dispatcher = request.getRequestDispatcher(nextPage);
		dispatcher.forward(request, response);
	}

	private void sendEmail(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// The user has clicked Send on the Email Defect form, so the form data needs to
		// be processed.  The steps are:
		// 1. Get the data values from the form and put them into local variables.  These
		// specify the addressee, reply-to, subject, user-entered message, and closing text.
		// 2. Call the EmailSender, passing in the local variables.
		// 3. Based on the status returned, build either a success or error message and
		// display status.jsp.

		EmailSender email = new EmailSender();
		String sendTo = (String)request.getParameter("sendTo");
		String replyTo = (String)request.getParameter("replyTo");
		String subject = (String)request.getParameter("subjectLine");
		String emailBody = (String)request.getParameter("message") +
				"\n\n\n" +
				(String)request.getParameter("emailClosingText");

		/*// Display the data values
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<head>");
		out.println("<title>Team C Defect System</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<p>Ready to send email message</p>");
		out.println("<p>sendTo: " + sendTo + "</p>");
		out.println("<p>replyTo: " + replyTo + "</p>");
		out.println("<p>subject: " + subject + "</p>");
		out.println("<p>emailBody: " + emailBody + "</p>");
		out.println("</body>");
		out.println("</html>"); */

		boolean status = false;

		try {
			status = email.SendTLS(sendTo, replyTo, subject, emailBody);
		} catch (Exception e) {
			request.setAttribute("message", e.getMessage());
		} finally {
    		if (status) {
    			request.setAttribute("msgType", "success");
    			request.setAttribute("message", "Email has been sent.");
    		} else {
    			request.setAttribute("msgType", "error");
    		}
    		// Forward the request to the appropriate page.
    		RequestDispatcher dispatcher = request.getRequestDispatcher("status.jsp");
    		dispatcher.forward(request, response);
		}
	}

	private void displayHomePage(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// Remove any session attributes related to the defect last acted upon,
		// which might be hanging around. The user must now select a defect in order
		// to perform an action on it.
		HttpSession session = request.getSession();
		session.removeAttribute("currentDefectId");
		session.removeAttribute("currentDefect");
		session.removeAttribute("newDefect");

		request.setAttribute("defectlistmessage", "");

		// To return to the homepage, set up the JSP forward, and forward the request.
		RequestDispatcher dispatcher = request.getRequestDispatcher("displayhomepage");
		dispatcher.forward(request, response);

	}
}
